#!/bin/bash

# Ensure job control is enabled
set -o monitor

if [ -z "$SHELL" ]; then
    SHELL=/bin/bash
fi

env=$(which env)
cygstart=$(which cygstart)
cmdpath=$(dirname $(which cmd))

subcyg_root=${1%/}
shift

trap 'rm -f "$subcyg_root$outtmp" "$subcyg_root$pidtmp"' EXIT

tmpfile_name() {
    tmp=$(mktemp)
    rm -f "$tmp"
    echo "$tmp"
}

outtmp=$(tmpfile_name)
pidtmp=$(tmpfile_name)

clean_env="$env -i PATH=$cmdpath"
subcyg_shell="$clean_env $cygstart --wait --hide ${subcyg_root}$SHELL"

on_interrupt() {
    # Use a second subcyg shell to forward the SIGINT through to the first
    # subcyg, interrupting whatever process it's running
    if [ -e "$subcyg_root$pidtmp" ]; then
        $subcyg_shell -l -c "'""kill -- -$(cat "$subcyg_root$pidtmp")""'"
    fi
    exit $(kill -l SIGINT)
}

trap 'on_interrupt' INT
# NOTE: Have to be *very* careful about quoting everything after the -c
# This does not yet cover all cases
$subcyg_shell -l -c "'(""$@"') >'$outtmp' 2>&1 & cat /proc/$!/pgid >'$pidtmp'; wait $!'"'" &
pid=$!

# We can't simply do a fd redirect from the temp file to console this script is
# running in, since they're in different Cygwins that don't know about each
# other.  In other words, this Cygwin can't simply follow writes to outtmp.  So
# instead we just watch it with tail
#
# Some commands don't produce any output, so also ensure that the output file
# exists first.  But wait at least a second for the file to show up since
# sometimes there can be a delay.
sleep 1
if [ -f "$subcyg_root$outtmp" ]; then
    tail -F --pid=$pid "$subcyg_root$outtmp" 2>/dev/null
    if [ $? -eq 130 ]; then
        # tail was interrupted by Ctrl-C, so treat this as though the
        # wrapped command were terminated as well.
        on_interrupt
    fi
fi

wait $pid
exit $?
